# -*- coding: utf-8 -*-

# dialogs/compression.py

# Copyright 2009-2010 Diego Hansen Hahn (aka DiegoHH) <diegohh90 [at] hotmail [dot] com>

# lazynds is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License.

# lazynds is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with lazynds. If not, see <http://www.gnu.org/licenses/>.

import array
import os
import tempfile

import gtk
import gobject

from structure import *
import widgets
import pluginmanager
import default

def populate_combo_box(cb, items):
    model = gtk.ListStore(gobject.TYPE_STRING)
    for x in items:
        model.append([x])
    cb.set_model(model)
    cell = gtk.CellRendererText()
    cb.pack_start(cell, True)
    cb.add_attribute(cell, 'text', 0)

class Compression:

    def __init__(self, builder, parent):
        self.builder = builder

        self.dialog = self.builder.get_object('compression_dialog')
        self.dialog.set_transient_for(parent)

        self.rb_bios_comp = self.builder.get_object('rb_bios_comp')
        self.rb_bios_comp.connect('toggled', self.on_rb_bios_comp_toggled)

        self.rb_plugins_comp = self.builder.get_object('rb_plugins_comp')
        self.rb_plugins_comp.connect('toggled', self.on_rb_plugins_comp_toggled)

        self.cb_bios_comp = self.builder.get_object('cb_bios_comp')
        self.cb_bios_comp.connect('changed', self.on_cb_bios_comp_changed)

        self.cb_plugins_comp = self.builder.get_object('cb_plugins_comp')
        self.cb_plugins_comp.connect('changed', self.on_cb_plugins_comp_changed)

        self.cmp_image_offset = widgets.HexSpinButton()
        self.cmp_image_offset.set_size_request(130,-1)
        self.builder.get_object('hbox20').pack_start(self.cmp_image_offset, True, True)
        self.cmp_image_offset.show()

        self.palette_offset = widgets.HexSpinButton()
        self.palette_offset.set_size_request(130,-1)
        self.builder.get_object('hbox24').pack_start(self.palette_offset, True, True)
        self.palette_offset.show()

        self.f_img_compress = self.builder.get_object('f_img_compress')
        self.f_img_pointers = self.builder.get_object('f_img_pointers')
        self.f_pal_import = self.builder.get_object('f_pal_import')
        self.f_pal_import.connect('toggled', self.on_f_pal_import_toggled)


    def run(self, fd, data, palette, type, bios, plugins):

        self.rb_bios_comp.set_active(True)
        self.cb_bios_comp.set_sensitive(True)

        self.keys = [[],[]]
        self.values = [[],[]]

        _keys = []
        for key in bios.FLAGS.keys():
            _keys.append(key)
        _keys = sorted(_keys)
        self.keys[0] = _keys
        self.values[0] = [bios.FLAGS[key] for key in _keys]

        for _dict in plugins:
            self.keys[1].append(_dict['Prefix'])
            self.values[1].append(_dict['Name'])

        populate_combo_box(self.cb_bios_comp, ["Compressões da BIOS"] + self.values[0])
        populate_combo_box(self.cb_plugins_comp, ["Compressões dos Plugins"] + self.values[1])

        self.cb_bios_comp.set_active(0)
        self.cb_plugins_comp.set_active(0)

        self.f_pal_import.set_active(False)

        if palette:
            self.f_pal_import.set_sensitive(True)
        else:
            self.f_pal_import.set_sensitive(False)

        self.compression = None

        while True:
            if self.dialog.run() == gtk.RESPONSE_OK:
                if not self.compression and self.f_img_compress.get_active():
                    default.Error(self.dialog, '''Nenhuma compressão foi selecionada.''')
                else:
                    break
            else:
                self.cb_bios_comp.get_model().clear()
                self.cb_bios_comp.clear()
                self.cb_plugins_comp.get_model().clear()
                self.cb_plugins_comp.clear()

                self.dialog.set_sensitive(True)
                self.dialog.hide()
                return False  # <------- Ver os retornos

        actions = {}

        self.dialog.set_sensitive(False)
        address = int(self.cmp_image_offset.get_value())

        # Verifica se deve ou não comprimir
        if self.f_img_compress.get_active():
            buffer = bios.compress(data, self.compression)
        else:
            buffer = array.array('c', data.read())

        actions.update({'data':[address, buffer]})

        ret = False
        # Verifica se deve atualizar os ponteiros
        if self.f_img_pointers.get_active():
            if type[0] == 'gba':
                ret = getGbaPointer(fd, address)
                if not ret:
                    default.Warning(self.dialog, gtk.BUTTONS_OK, "O endereço original não foi encontrado na ROM.")
            elif type[0] == 'nds':
                ret = getNdsFatEntry(fd, address, type[1])
                if not ret:
                    default.Warning(self.dialog, gtk.BUTTONS_OK, "O endereço original não foi encontrado na FAT.")
            else:
                default.Warning(self.dialog, gtk.BUTTONS_OK, "O arquivo aberto pelo lazynds não suporta atualização de ponteiros.")

            actions.update({'pointer':[address, ret]})
        # Verifica se deve importar a paleta

        # Confirmar esta parte
        if self.f_pal_import.get_active():
            address = int(self.palette_offset.get_text(), 16)
            actions.update({'palette':[address, palette]})

        self.cb_bios_comp.get_model().clear()
        self.cb_bios_comp.clear()
        self.cb_plugins_comp.get_model().clear()
        self.cb_plugins_comp.clear()

        self.dialog.set_sensitive(True)
        self.dialog.hide()
        return actions

    def on_rb_bios_comp_toggled(self, widget):
        if widget.get_active():
            self.cb_bios_comp.set_sensitive(True)
        else:
            self.cb_bios_comp.set_sensitive(False)

    def on_rb_plugins_comp_toggled(self, widget):
        if widget.get_active():
            self.cb_plugins_comp.set_sensitive(True)
        else:
            self.cb_plugins_comp.set_sensitive(False)

    def on_cb_bios_comp_changed(self, widget):
        if widget.get_active() == 0:
            self.compression = None
        else:
            self.compression = self.keys[0][widget.get_active()-1]

    def on_cb_plugins_comp_changed(self, widget):
        if widget.get_active() == 0:
            self.compression = None
        else:
            self.compression = self.keys[1][widget.get_active()-1]

    def on_f_pal_import_toggled(self, widget):
        self.palette_offset.set_sensitive(widget.get_active())